package model

import (
	"common/helper"
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	g "github.com/doug-martin/goqu/v9"
	"strconv"
)

func PlatformUpdate(adminID, adminName, id string, state, maintained, seq int) error {

	data := Platform{}
	query, _, _ := dialect.From("tbl_platforms").Select(colsPlatform...).Where(g.Ex{"id": id}).Limit(1).ToSQL()
	err := meta.MerchantDB.Get(&data, query)
	if err != nil && err != sql.ErrNoRows {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if err == sql.ErrNoRows {
		return errors.New(helper.RecordNotExistErr)
	}

	if 0 == state && 0 == maintained && 0 == seq {
		return errors.New(helper.NoDataUpdate)
	}

	if data.State == state && data.Maintained == maintained && data.Seq == seq {
		return errors.New(helper.NoDataUpdate)
	}

	record := g.Record{
		"updated_uid":  adminID,
		"updated_name": adminName,
	}
	if state != 0 {
		record["state"] = state

	}
	if maintained != 0 {
		record["maintained"] = maintained
	}
	if seq != 0 {
		record["seq"] = seq
	}

	maxid, err := strconv.Atoi(id)
	if state != 0 {
		online := "0"
		if state == 1 {
			online = "1"
		}
		if state == 2 {
			online = "0"
		}

		sql := "update tbl_game_lists set online=" + online + " where platform_id>=" + id + " and platform_id<" + strconv.Itoa(maxid+100)

		_, err = meta.MerchantDB.Exec(sql)
		if err != nil {
			return pushLog(fmt.Errorf("%s,[%s]", err.Error(), sql), "数据库错误")
		}
	}
	if maintained != 0 {
		query, _, _ = dialect.Update("tbl_platforms").Set(record).Where(g.Ex{"id": id}).ToSQL()
		_, err = meta.MerchantDB.Exec(query)
		if err != nil {
			return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}
	}
	query, _, _ = dialect.Update("tbl_platforms").Set(record).Where(g.Ex{"id": id}).ToSQL()

	_, err = meta.MerchantDB.Exec(query)
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	GameFlushAll()
	_ = LoadPlatforms()

	return nil
}

func PlatformList(ex g.Ex, page, pageSize int) (PlatformData, error) {

	data := PlatformData{
		S: pageSize,
	}
	t := dialect.From("tbl_platforms")
	if page >= 1 {
		query, _, _ := t.Select(g.COUNT(1)).Where(ex).ToSQL()

		err := meta.MerchantDB.Get(&data.T, query)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}

	}

	offset := (page - 1) * pageSize
	query, _, _ := t.Select(colsPlatform...).Where(ex).
		Order(g.C("created_at").Desc()).Offset(uint(offset)).Limit(uint(pageSize)).ToSQL()
	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return data, nil
}

func GetPlatformByPid(pid string) ([]Platform, error) {

	data := []Platform{}
	query := "select id,pid,name,maintained,state,seq from tbl_platforms where pid=" + pid + " order by id asc"
	if pid == "1" {
		query = "select id,pid,name,maintained,state,seq from tbl_platforms where pid=0 and id<3000 order by id asc"
	} else if pid == "2" {
		query = "select id,pid,name,maintained,state,seq from tbl_platforms where pid=0 and id>=3000 order by id asc"
	}

	err := meta.MerchantDB.Select(&data, query)
	if err != nil {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return data, nil
}

type Nav struct {
	Status bool               `json:"status"`
	Data   map[int][]platJson `json:"data"`
}

func LoadPlatforms() error {

	var (
		data []platJson
		nav  = Nav{
			Status: true,
		}
	)
	nav.Data = make(map[int][]platJson)
	ex := g.Ex{
		"state": 1,
	}
	query, _, _ := dialect.From("tbl_platforms").
		Select(colsPlatJson...).Where(ex).Where(g.I("pid").Neq(0)).Order(g.C("game_type").Asc(), g.C("seq").Asc()).ToSQL()
	query = "/* master */ " + query

	err := meta.MerchantDB.Select(&data, query)
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if len(data) == 0 {
		return errors.New(helper.RecordNotExistErr)
	}

	pipe := meta.MerchantRedis.Pipeline()
	defer pipe.Close()

	for _, v := range data {
		if _, ok := nav.Data[v.GameType]; !ok {
			nav.Data[v.GameType] = []platJson{v}
		} else {
			nav.Data[v.GameType] = append(nav.Data[v.GameType], v)
		}

		k := fmt.Sprintf("plat:%s", v.ID)
		b, _ := json.Marshal(v)
		pipe.Del(ctx, k)
		pipe.Set(ctx, k, string(b), 0)
		pipe.Persist(ctx, k)
	}

	navBytes, _ := json.Marshal(nav)
	navKey := "nav"
	pipe.Del(ctx, navKey)
	pipe.Set(ctx, navKey, string(navBytes), 0)
	pipe.Persist(ctx, navKey)
	_, err = pipe.Exec(ctx)
	if err != nil {
		return pushLog(err, helper.RedisErr)
	}

	return nil
}
